﻿package model.unit 
{
	import constant.CampConst;
	import core.Vector2D;
	import event.HeartbeatEvent;
	import manager.UnitManager;
	import model.battle.Army;
	import model.battle.Heartbeat;
	import roleView.RoleSkin;
	import utils.MathUtil;
	import view.ISkin;
	/**
	 * ...
	 * @author ...
	 */
	public class AbsUnit 
	{
		
		protected var _id:uint = 0;
		
		/**
		 * 速度
		 */
		public var speed:uint = 3;
		
		/**
		 * 射程
		 */
		public var rangeR:uint = 60;
		
		/**
		 * 视野半径
		 */
		public var viewR:uint = 300;//
		
		/**
		 * 阵营
		 */
		protected var _camp:uint = CampConst.LEFT;
		
		protected var heartbeat:Heartbeat;
		protected var skin:ISkin;
		protected var target:AbsUnit;//锁定的目标
		
		protected var _postion:Vector2D;
		
		public function AbsUnit(id:uint)
		{
			this._id = id;
			heartbeat = UnitManager.instance.heartbeat;
			heartbeat.addEventListener(HeartbeatEvent.BEAT, onHeartbeat);
		}
		
		public function set position(value:Vector2D):void
		{
			this._postion = value;
		}
		
		public function get position():Vector2D
		{
			return _postion;
		}
		
		
		public function setSkin(value:ISkin):void 
		{
			skin = value;
			var rs:RoleSkin = skin as RoleSkin;
		}
		
		public function getSkin():ISkin 
		{
			return skin;
		}
		
		private function onHeartbeat(e:HeartbeatEvent):void 
		{
			runAI();
		}
		
		protected function runAI():void
		{
			ai_start();
			
		}
		
		
		protected function ai_start():void
		{
			checkHasTarget();
		}
		
		/**
		 * 寻找视野内的技能目标，子类复写
		 * @return
		 */
		protected function ai_searchTarget():void
		{
			var arr:Array = $getEnemyArmy().sort();
			var l:uint = arr.length;
			var tUnit:AbsUnit;//临时记录单位
			var tDSQ:int = 0;//临时记录距离的平方
			var minSQ:int = 9999999;//已经遍历过的对象中的最短距离
			for (var i:uint = 0; i < arr.length; i++)
			{
				tUnit = arr[i];
				tDSQ = (this.position).distSQ(tUnit.position);	//和另一个单位的距离的平方
				
				if (tDSQ < this.viewR * this.viewR && tDSQ < minSQ )//如果视野内有更近的目标
				{
					minSQ = tDSQ;
					target = tUnit;
					trace(">>更新目标:",target)
				}
			}
			
			check_searchResult();
		}
		
		protected function $getEnemyArmy():Army
		{
			if (_camp == CampConst.LEFT)
			{
				return Army.rArmy;
			}
			return Army.lArmy;
		}
			
		/**
		 * @see ai_searchTarget()
		 * 检查ai_searchTarget 的结果
		 */
		private function check_searchResult():void
		{
			if (target)
			{
				checkTargetInRange();
			}
			else
			{
				ai_forward();
			}
		}
		
		/**
		 * 施放技能
		 */
		protected function ai_cast():void
		{
			//trace(">>", this, "ai_cast");
		}
		
		/**
		 * 前进
		 */
		protected function ai_forward():void
		{
			//trace(">>", this, "ai_forward");
			var d:Vector2D = new Vector2D();
			d.length = speed;
			
			if (_camp == CampConst.LEFT)
			{
				d.angle = 0;//TODO
			}
			else
			{
				d.angle = 180;
			}
			
			this._postion = this._postion.add(d);
			updateSkin();
		}
		
		protected function updateSkin():void
		{
			skin.moveto(this._postion);
		}
		
		/**
		 * 向目标靠拢
		 */
		protected function ai_movetoTarget():void
		{
			//trace(">>", this, "ai_movetoTarget");
			forwardPosition(target.position);
			updateSkin();
		}
		
		/**
		 * 向某一点移动
		 * @param	pos
		 */
		protected function forwardPosition(pos:Vector2D):void
		{
			if (MathUtil.dis_lt(this._postion, pos, this.speed))
			{
				this._postion = pos;
				return;
			}
			var d:Vector2D = new Vector2D(speed, 0);
			d.angle = (pos.subtract(this.position)).angle;
			
			this._postion = this._postion.add(d);
		}
		
		
		/**
		 * 目标值是否存在
		 * @return
		 */
		protected function checkHasTarget():void
		{
			if (target)
			{
				checkTargetEnable();
			}
			else
			{
				ai_searchTarget();
			}
		}
		
		/**
		 * 目标是否依然有效，如果目标死亡、消失、离开视野等，视为无效
		 * @return
		 */
		protected function checkTargetEnable():void
		{
			var enable:Boolean = true;
			if (enable)
			{
				checkTargetInRange();
			}
			else
			{
				ai_searchTarget();
			}
		}
		
		/**
		 * 目标是否在视野内
		 * @return
		 */
		protected function checkTargetInView():void
		{
			//trace("checkTargetInView")
			if (MathUtil.dis_lt(this._postion, target.position, this.viewR))//在視野内
			{
				ai_movetoTarget();
			}
			else
			{
				ai_searchTarget();
			}
		}
		
		/**
		 * 目标是否在射程内
		 * @return
		 */
		protected function checkTargetInRange():void
		{
			//trace("checkTargetInRange")
			if (MathUtil.dis_lt(this._postion, target.position, this.rangeR)) //在射程内
			{
				ai_cast();
			}
			else
			{
				checkTargetInView();
			}
		}
		
		public function set camp(value:uint):void 
		{
			_camp = value;
		}
		
		public function get camp():uint 
		{
			return _camp;
		}
		
		public function get id():uint 
		{
			return _id;
		}
		
		public function toString():String 
		{
			return "[AbsUnit camp=" + camp + " id=" + id + "]";
		}
	}

}